﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using Microsoft.Practices.EnterpriseLibrary.Data;
using System.Data.Common;

namespace Runda.CMS.Common.GenerateFunc
{
    class Program
    { 
            static Dictionary<int, string> Funs = new Dictionary<int, string>();

            static void Main(string[] args)
            {
                StringBuilder s = new StringBuilder();
                //s.AppendLine("Delete from Cms_Sys_UserFunctionRelation");
                s.AppendLine("Delete from Cms_Sys_RoleFunctionRelation ");
                s.AppendLine("Delete from Cms_Sys_UserRoleRelation ");
                s.AppendLine("Delete from Cms_Sys_Function");
                s.AppendLine("Delete from Cms_Sys_Role ");
                s.AppendLine();
                s.Append(GenerateFunc());
                s.Append(GenerateRole());
                s.Append(GenerateRoleFunction());

                s.Append(GenerateUserRole());
                File.WriteAllText("InitPermission.sql", s.ToString());

                Database db = DatabaseFactory.CreateDatabase();
                DbCommand dbCommand = db.GetSqlStringCommand(s.ToString());
                db.ExecuteNonQuery(dbCommand);
            }
            #region Function
            static string GenerateFunc()
            {
                List<string> OutPut = new List<string>();

                XmlDocument doc = new XmlDocument();
                doc.Load("../../Function.xml");

                XmlNodeList nl = doc.GetElementsByTagName("Root");
                foreach (XmlNode node in nl[0].ChildNodes)
                {
                    FindChild(ref OutPut, node, "NULL");
                }

                StringBuilder sb = new StringBuilder();
                foreach (string str in OutPut)
                {
                    sb.AppendLine(str);
                }
                sb.AppendLine("");
                return sb.ToString();
            }
            static void FindChild(ref List<string> output, XmlNode node, string ParentCode)
            {
                output.Add(MakeSqlString(node, ParentCode));

                foreach (XmlNode n in node.ChildNodes)
                {
                    FindChild(ref output, n, node.Attributes["FunCode"].Value.ToString());
                }
            }
            static string MakeSqlString(XmlNode node, string Parent)
            {
                string SQL = @"IF EXISTS({2})
UPDATE Cms_Sys_Function SET {0} 
ELSE
INSERT INTO [Cms_Sys_Function] ([FuncId],[FFuncId],[FuncName],[IsMenu],[URL],[ImageUrl],[Target]	,[Description],deleted)  VALUES {1}";
                string FuncId = "'" + node.Attributes["FunCode"].Value.ToString() + "'";
                string FFuncId = "'" + Parent + "'";
                if (Parent.ToLower() == "null")
                {
                    FFuncId = "NULL";
                }
                string FuncName = "N'" + node.Attributes["Name"].Value.ToString() + "'";
                string m = node.Attributes["IsMenu"].Value.ToString() == "true" ? "1" : "0";
                string IsMenu = "'" + m + "'";
                string URL = "'" + node.Attributes["URL"].Value.ToString() + "'";
                string ImageUrl = "'" + node.Attributes["ImageUrl"].Value.ToString() + "'";
                string Target = "'" + node.Attributes["Target"].Value.ToString() + "'";
                string Description = "NULL";
                //string CreatedOn = "getdate()";
                //string CreatedBy = "'System'";
                //string LastModifiedOn = "getdate()";
                //string LastModifiedBy = "'System'";

                string sfun = node.Attributes["FunCode"].Value.ToString();

                int funid = Convert.ToInt32(sfun.Replace("Func", ""));
                Funs.Add(funid, FuncId);

                string SQL2 = "(" + FuncId + "," + FFuncId + "," + FuncName + "," + IsMenu + ","
                                + URL + "," + ImageUrl + "," + Target + "," + Description + ",0)";

                string SQL3 = " FFuncId=" + FFuncId + ",FuncName=" + FuncName + ",IsMenu=" + IsMenu + ",URL=" + URL + ",ImageUrl=" + ImageUrl + ",Target=" + Target + ",Description=" + Description + " where FuncId=" + FuncId;
                string sql4 = "select 1 from Cms_Sys_Function where FuncId=" + FuncId;
                return string.Format(SQL, SQL3, SQL2,sql4);
            }
            #endregion

            #region Role
            static string GenerateRole()
            {
                List<string> OutPut = new List<string>();

                XmlDocument doc = new XmlDocument();
                doc.Load("../../RoleFunction.xml");

                XmlNodeList nl = doc.GetElementsByTagName("Root");
                foreach (XmlNode node in nl[0].ChildNodes)
                {
                    OutPut.Add(GenerateRoleSQL(node));
                }


                StringBuilder sb = new StringBuilder();
                foreach (string str in OutPut)
                {
                    sb.AppendLine(str);
                }
                sb.AppendLine("");
                return sb.ToString();

            }
            static string GenerateRoleSQL(XmlNode node)
            {
                string SQL = "INSERT INTO [Cms_sys_Role] ([RoleId],[RoleName],[RoleDesc],[IsSystem],[Deleted],[CreatedOn]) VALUES";

                string RoleId = "N'" + node.Attributes["GUID"].Value.ToString() + "'";
                string RoleName = "N'" + node.Attributes["Name"].Value.ToString() + "'";
                string Description = "N'" + node.Attributes["Desc"].Value.ToString() + "'";
                string SystemCode = "NULL";
                if (node.Attributes["SystemCode"] != null)
                    SystemCode = "N'" + node.Attributes["SystemCode"].Value.ToString() + "'";

                string IsSystem = "'" + node.Attributes["IsSys"].Value.ToString() + "'";
                string Deleted = "0";
                string CreatedOn = "getdate()";

                string SQL2 = "(" + RoleId + "," + RoleName + "," + Description + "," + IsSystem + ","
                                 + Deleted + ","
                                + CreatedOn + ")";


                return SQL + SQL2;

            }
            #endregion

            #region Role Function
            static string GenerateRoleFunction()
            {
                List<string> OutPut = new List<string>();

                XmlDocument doc = new XmlDocument();
                doc.Load("../../RoleFunction.xml");

                XmlNodeList nl = doc.GetElementsByTagName("Root");

                //find role
                foreach (XmlNode node in nl[0].ChildNodes)
                {
                    string RoleID = node.Attributes["GUID"].Value;
                    //find func
                    foreach (XmlNode n in node.ChildNodes)
                    {
                        if (n.Name.ToUpper() == "FUNCPOINT")
                        {
                            string id = n.Attributes["ID"].Value;
                            if (id.Length == 0)
                                continue;
                            OutPut.Add(GenerateRoleFuncSql(RoleID, Convert.ToInt32(id)));
                        }
                        if (n.Name.ToUpper() == "FUNCREGION")
                        {
                            string from = n.Attributes["From"].Value;
                            string to = n.Attributes["To"].Value;
                            string denyFuncs = "";
                            if (n.Attributes["Deny"] != null)
                                denyFuncs = n.Attributes["Deny"].Value;
                            List<string> lstr = GenerateRoleFuncSql(RoleID, Convert.ToInt32(from), Convert.ToInt32(to), denyFuncs);
                            foreach (string s in lstr)
                            {
                                OutPut.Add(s);
                            }
                        }

                    }
                }

                StringBuilder sb = new StringBuilder();
                foreach (string str in OutPut)
                {
                    sb.AppendLine(str);
                }
                sb.AppendLine("");
                return sb.ToString();
            }

            static string GenerateRoleFuncSql(string Role, int Fun)
            {

                string SQL = "INSERT INTO [Cms_Sys_RoleFunctionRelation] ([ID],[RoleId],[FuncId],Deleted) VALUES";

                string RoleFunctionId = "'" + Guid.NewGuid().ToString() + "'";
                string RoleId = "'" + Role + "'";
                string FuncId = Funs[Fun];

                string SQL2 = "(" + RoleFunctionId + "," + RoleId + "," + FuncId + ",0)";

                return SQL + SQL2;
            }
            static string GenerateRoleFuncSql(string Role, string Fun)
            {

                string SQL = "INSERT INTO [Cms_Sys_RoleFunctionRelation] ([ID],[RoleId],[FuncId],Deleted) VALUES";

                string RoleFunctionId = "'" + Guid.NewGuid().ToString() + "'";
                string RoleId = "'" + Role + "'";
                string FuncId = Fun;

                string SQL2 = "(" + RoleFunctionId + "," + RoleId + "," + FuncId + ",0)";

                return SQL + SQL2;
            }

            static List<string> GenerateRoleFuncSql(string Role, int from, int to, string denyFuncs)
            {
                List<string> ret = new List<string>();

                int[] arr = new int[Funs.Keys.Count];
                Funs.Keys.CopyTo(arr, 0);

                for (int i = 0; i < arr.Length; i++)
                {
                    int funcId = arr[i];
                    if (funcId >= from && funcId <= to && !denyFuncs.Contains(";" + funcId + ";"))
                    {
                        ret.Add(GenerateRoleFuncSql(Role, Funs[arr[i]]));
                    }
                }

                return ret;
            }
            #endregion

            #region userrole

            static string GenerateUserRole()
            {
                List<string> OutPut = new List<string>();

                XmlDocument doc = new XmlDocument();
                doc.Load("../../UserRole.xml");

                XmlNodeList nl = doc.GetElementsByTagName("Root");

                //find role
                foreach (XmlNode node in nl[0].ChildNodes)
                {
                    string RoleID = node.Attributes["GUID"].Value;
                    //find func
                    foreach (XmlNode n in node.ChildNodes)
                    {
                        if (n.Name.ToUpper() == "USER")
                        {
                            string id = n.Attributes["UserID"].Value;
                            OutPut.Add(GenerateUserRoleSQL(RoleID, id));
                        }
                    }
                }

                StringBuilder sb = new StringBuilder();
                foreach (string str in OutPut)
                {
                    sb.AppendLine(str);
                }
                sb.AppendLine("");
                return sb.ToString();


            }

            static string GenerateUserRoleSQL(string Roleid, string NtAccount)
            {
                string sql = "INSERT INTO [Cms_Sys_UserRoleRelation]([ID],[RoleId],[UserID]) VALUES ";

                string key = "'" + Guid.NewGuid().ToString() + "'";
                string role = "'" + Roleid + "'";
                string emp = "'" + NtAccount + "'";

                string sql2 = "(" + key + "," + role + "," + emp + ")";

                return sql + sql2;
            }
            #endregion
        }
    }
 
